﻿using System;
using CrmService.Enums;
using CrmService.Repository;
using CrmService.Models.Data;
using System.Collections.Generic;
using CrmService.Repository.Interfaces;

namespace CrmService.Services
{

    /// <summary>
    ///     This class interacts with the Repository to perform CRUD operations on the 
    ///     Crm DB.
    /// </summary>
    /// <remarks>
    ///     CRMService is not meant to be exposed as REST service and does not do exception handling.
    ///     It will simply throw a FaultException handled appropriately by its consumers. 
    /// </remarks>
    public class CrmDataService : ICrmDataService
    {

        #region ICrmService Members

        /// <summary>
        ///     Instance of CrmRepository to be used
        /// </summary>
        private readonly ICrmRepository _dataRepository;

        /// <summary>
        ///     Default constructor. Instantiates the default instance for the
        ///     ICrmRepository
        /// </summary>
        public CrmDataService()
        {
            _dataRepository = new CrmRepository();
        }

        /// <summary>
        ///     Overloaded constructor for dependency injection
        /// </summary>
        /// <param name="repository">
        ///     The ICrmRepository instance to be used.
        /// </param>
        public CrmDataService(ICrmRepository repository)
        {
            _dataRepository = repository;
        }

        /// <summary>
        ///     Method to add ideas to the CrmDatabase
        /// </summary>
        /// <param name="ideas">
        ///     The ideas to be added
        /// </param>
        public void AddIdeas(IEnumerable<Idea> ideas)
        {
            _dataRepository.AddIdeas(ideas);
        }

        /// <summary>
        ///     Method to get the approved/rejected ideas from the Crm Database
        /// </summary>
        /// <returns>
        ///     List of accepted/rejected ideas.
        /// </returns>
        public IEnumerable<Idea> GetSyncedIdeas()
        {
            IEnumerable<Idea> acceptedList = _dataRepository.FindIdeasByStatus(IdeaStatus.Accepted);
            IEnumerable<Idea> rejectedList = _dataRepository.FindIdeasByStatus(IdeaStatus.Rejected);
            List<Idea> ideaList = new List<Idea>();
            ideaList.AddRange(acceptedList);
            ideaList.AddRange(rejectedList);
            return ideaList;
        }

        /// <summary>
        ///     Method to get the list of successfully synced ideas so they
        ///     can be removed from the Crm DB
        /// </summary>
        /// <param name="ideas">
        ///     The list of successfully synced ideas
        /// </param>
        public void IdeasSuccessfullySynced(IEnumerable<Idea> ideas)
        {
            foreach (Idea idea in ideas)
            {
                Idea dbIdea = _dataRepository.FindById(idea.IdeaId);
                _dataRepository.DeleteIdea(dbIdea);
            }
        }

        /// <summary>
        ///     Method to get the list of ideas to be approved/rejected
        /// </summary>
        /// <returns>
        ///     The list of ideas to be approved/rejected
        /// </returns>
        public IEnumerable<Idea> GetIdeasForApproval()
        {
            return _dataRepository.GetAllIdeas();
        }

        /// <summary>
        ///     Method to mark an idea as accepted
        /// </summary>
        /// <param name="ideaId">
        ///     Idea that has been accepted
        /// </param>
        public void AcceptIdea(int ideaId)
        {
            Idea dbIdea = _dataRepository.FindById(ideaId);
            dbIdea.Status = (byte)IdeaStatus.Accepted;
            dbIdea.StatusLastUpdatedOn = DateTime.Now;
            dbIdea.Comments = "";
            _dataRepository.Update();
        }

        /// <summary>
        ///     Method to mark an idea as under review
        /// </summary>
        /// <param name="ideaId">
        ///     Idea that has been accepted
        /// </param>
        public void ResetToReview(int ideaId)
        {
            Idea dbIdea = _dataRepository.FindById(ideaId);
            dbIdea.Status = (byte)IdeaStatus.Reviewing;
            dbIdea.StatusLastUpdatedOn = DateTime.Now;
            _dataRepository.Update();
        }

        /// <summary>
        ///     Method to mark an idea as rejected
        /// </summary>
        /// <param name="ideaId">
        ///     Idea that has been rejected
        /// </param>
        /// <param name="rejectionReason">
        ///     Reason for rejection
        /// </param>
        public void RejectIdea(int ideaId, string rejectionReason)
        {
            Idea dbIdea = _dataRepository.FindById(ideaId);
            dbIdea.Status = (byte)IdeaStatus.Rejected;
            dbIdea.StatusLastUpdatedOn = DateTime.Now;
            dbIdea.Comments = rejectionReason;
            _dataRepository.Update();
        }

        #endregion
    }
}
